package com.bub.pay.framework.shiro.realm;

import com.alibaba.fastjson.JSON;
import com.bub.pay.framework.common.entity.model.SessionModel;
import com.bub.pay.framework.redis.RedisClient;
import com.bub.pay.framework.redis.RedisKeyPrefix;
import com.bub.pay.framework.shiro.authc.BNSimpleAuthenticationInfo;
import com.bub.pay.framework.shiro.authc.UserToken;
import com.bub.pay.core.entity.domain.SysRole;
import com.bub.pay.core.entity.domain.SysUser;
import com.bub.pay.core.manager.role.RoleManager;
import com.bub.pay.core.manager.user.UserCommonManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;

import static com.bub.pay.framework.common.constant.SystemConstants.USER_INFO;

@Slf4j
public class UserRealm extends AuthorizingRealm {

	@Resource
	private RoleManager roleManager;

	@Resource
	private RedisClient redisClient;

	@Resource
	private UserCommonManager userCommonManager;

	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		String username = (String) super.getAvailablePrincipal(principalCollection);
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

		Subject subject = SecurityUtils.getSubject();
		SessionModel sessionModel = (SessionModel) subject.getSession().getAttribute(USER_INFO);

		boolean refreshFlag = false;
		if (!redisClient.exists(RedisKeyPrefix.CACHE, sessionModel.getAuthToken())) {
			redisClient.set(RedisKeyPrefix.CACHE, sessionModel.getAuthToken(), 1800);
			refreshFlag = true;
		}

		List<SysRole> userRoles = roleManager.queryRolesByUserId(sessionModel.getUserId(), sessionModel.getUserType(),
				refreshFlag);

		if (userRoles == null)
			return authorizationInfo;
		HashSet<String> roles = new HashSet<>();
		log.info("roles:{}", JSON.toJSONString(roles));
		userRoles.forEach(role -> {
			// 角色编码
			roles.add(role.getCode());
		});
		authorizationInfo.addRoles(roles);
		authorizationInfo.addStringPermissions(
				roleManager.queryPremsByRoleId(userRoles, sessionModel.getUserType(), refreshFlag));
		return authorizationInfo;
	}

	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
			throws AuthenticationException {
		UserToken token = (UserToken) authenticationToken;
		String username = token.getUsername();
		SysUser query = new SysUser();
		query.setUserName(username);
		query.setPassword(new String(((UserToken) authenticationToken).getPassword()));
		query.setUserType(token.getUserType());
		SysUser user = userCommonManager.beforeLoginCheck(query,token.isLimitIp(), token.getReqIp());
		return new BNSimpleAuthenticationInfo(user.getId(), user.getExtendId(), token.getUserType(), username,
				user.getPassword(), getName());
	}
}
